package development.bussiness;

import state.AlertListener;
import state.GameAlert;
import state.GameGlobal;
import state.GameImage;
import state.ResourceManager;
import state.ResourceRms;
import state.Transformer;
import state.socket.DataPackage;
import state.util.GameStringUtils;
import state.util.Hashtable;
import state.util.array.ByteArray;
import state.util.array.StringArray;
import development.ChatComponent;
import development.Constants;
import development.FrmChooseApp;
import development.FrmDisplayNotificationMessage;
import development.FrmDownloadResource;
import development.FrmGuide;
import development.FrmMoneyToGoldExchange;
import development.FrmRegister;
import development.FrmUserInfo;
import development.Global;
import development.Rms;
import development.bean.Provider;
import development.bean.Service;
import development.bean.Session;
import development.bean.User;
import development.group.FrmGroupMenu;
import development.socket.ProtocolConstants;
import development.socket.SocketClientUtil;

public class AuthenticateBussiness implements AlertListener {
  private String updateUrl;

  public void alertEventPerform(int alertType, int eventType, int alertId) {
    if (alertId == 98) {
      if (eventType == GameAlert.YES_BUTTON) {
        // Tự động cập nhật phiên bản
        GameGlobal.getMidlet().platformRequest(updateUrl);
        GameGlobal.getMidlet().notifyDestroyed();
      }
    } else if ((alertId == 95) && (eventType == GameAlert.YES_BUTTON)) {
      Global.nextState(FrmRegister.instance(), null);
    }
  }

  public void onAuthenticateSuccess(DataPackage dataPackage) {
    String username = dataPackage.nextString();
    String sessionId = dataPackage.nextString();
    Global.HEART_BREATH_SEQUENCE_TIME = dataPackage.nextInt();
    String uuid = dataPackage.nextString();
    Global.authenClient.setHeartBreathSequenceTime(Global.HEART_BREATH_SEQUENCE_TIME);

    int numberOfGameServices = dataPackage.nextInt();
    Global.gameServices.removeAllElements();

    for (int i = 0; i < numberOfGameServices; i++) {
      Service gameService = new Service();
      gameService.setId(dataPackage.nextString());
      gameService.setName(dataPackage.nextString());
      gameService.setUrl(dataPackage.nextString());
      gameService.setPort(dataPackage.nextInt());
      gameService.setCocurrentUser(dataPackage.nextInt());
      gameService.setMaxUser(dataPackage.nextInt());
      Global.gameServices.addElement(gameService);
      if (i == 0) {
        SocketClientUtil.connectToGameServer(gameService.getUrl(), gameService.getPort(), Global.gameActionHandle);
        Global.currentGameService = gameService;
      }
    }

    Global.session = new Session(sessionId, Global.loginInfo.getUserName());
    Global.loginInfo.setUuid(uuid);
    Rms.saveSession(Global.loginInfo.getUserName(), sessionId);
    Rms.saveLoginInfo(Global.loginInfo);

    // Send the device solusion of client to server
    DataPackage deveiceSolusionPackage = DataPackage.createDataPackage1(ProtocolConstants.RequestHeader.CLIENT_DEVICE_NOTIFY_REQUEST);
    deveiceSolusionPackage.putInt(Constants.SCREEN_WIDTH);
    deveiceSolusionPackage.putInt(Constants.SCREEN_HEIGHT);
    Global.authenClient.write(deveiceSolusionPackage);
    
    // Send to server the client device name
    SocketClientUtil.sendDeviceInfo();

    // Nếu là tự động đăng nhập thì lưu lại là đã valid user này
    if (!username.equals(Global.waitingToValidUsername)) {
      Global.validedUsername = username;
    } else { // Nếu là do user đăng nhập thì chuyển sang form tiếp theo
      Global.waitingToValidUsername = null;
      GameGlobal.nextState1(FrmGroupMenu.instance(), null, Transformer.TRANSFORM_WITH_LOADING_FORM);
    }

    // Request lay ma lenh dich vu subscription
    requestSMSServiceCommand(Global.currentUser.getProviderId());
  }
  
  public void requestSMSServiceCommand(int providerId) {
    DataPackage dataPackage = DataPackage.createDataPackage1(ProtocolConstants.RequestHeader.SUBSCRIPTION_SMS_COMMAND_REQUEST);
    dataPackage.putInt(providerId);
    Global.authenClient.write(dataPackage);
  }

  public void onChatServiceInfoReceive(DataPackage dataPackage) {
    String id = dataPackage.nextString();
    String name = dataPackage.nextString();
    String url = dataPackage.nextString();
    int port = dataPackage.nextInt();
    int concurrentUser = dataPackage.nextInt();
    int maxUser = dataPackage.nextInt();

    if (Global.chatService != null) {
      Global.chatService.setId(id);
      Global.chatService.setName(name);
      Global.chatService.setUrl(url);
      Global.chatService.setPort(port);
      Global.chatService.setMaxUser(maxUser);
    } else {
      Global.chatService = new Service(id, name, url, port, maxUser);
    }
    Global.chatService.setCocurrentUser(concurrentUser);

    if (Global.chatClient == null) {
      SocketClientUtil.connectToChatServer(Global.chatService.getUrl(), Global.chatService.getPort(), Global.chatHandle);
      Global.chatComponent = new ChatComponent();
    }
  }

  public void onAppServiceInfoReceive(DataPackage dataPackage) {
    String id = dataPackage.nextString();
    String name = dataPackage.nextString();
    String url = dataPackage.nextString();
    int port = dataPackage.nextInt();
    int concurrentUser = dataPackage.nextInt();
    int maxUser = dataPackage.nextInt();

    if (Global.appService != null) {
      Global.appService.setId(id);
      Global.appService.setName(name);
      Global.appService.setUrl(url);
      Global.appService.setPort(port);
      Global.appService.setMaxUser(maxUser);
    } else {
      Global.appService = new Service(id, name, url, port, maxUser);
    }
    Global.appService.setCocurrentUser(concurrentUser);
    SocketClientUtil.connectToAppServer(Global.appService.getUrl(), Global.appService.getPort(), Global.appHandle);
  }

  public void onAuthenticateFail(DataPackage dataPackage) {
    String username1 = dataPackage.nextString();

    // Nếu là xác nhận user ngầm thì không làm gì cả
    if (!username1.equals(Global.waitingToValidUsername)) {
      return;
    }

    int errorId = dataPackage.nextInt();
    switch (errorId) {
    case ProtocolConstants.ErrorCode.ALREADY_ONLINE_ERROR:
      if ((Global.systemCanvas.frmCurrent == Global.alert) && (Global.alert.getAlertType() != GameAlert.LOADING_FORM)) {
        GameGlobal.alert.showAlert3(this, GameAlert.OK_TYPE, StringArray.create1( "Đăng nhập thất bại", "Tài khoản đang sử dụng" ));
      }
      break;
    case ProtocolConstants.ErrorCode.USER_BLOCK_ERROR:
      if (Global.systemCanvas.frmCurrent == Global.alert) {
        GameGlobal.alert.showAlert3(this, GameAlert.OK_TYPE, StringArray.create1( "Đăng nhập thất bại", "Tài khoản đã bị khóa" ));
      }
      break;
    case ProtocolConstants.ErrorCode.USER_NOT_EXIST_ERROR:
      if (Global.systemCanvas.frmCurrent == Global.alert) {
        GameGlobal.alert.showAlert1(this, GameAlert.YES_NO_TYPE, StringArray.create2( "Đăng nhập thất bại", "Tài khoản không tồn tại", "Bạn có muốn tạo tài khoản?" ), 95);
      }
      break;
    default:
      if (Global.systemCanvas.frmCurrent == Global.alert) {
        GameGlobal.alert.showAlert3(this, GameAlert.OK_TYPE, StringArray.create1( "Đăng nhập thất bại", "Mật khẩu không đúng" ));
      }
      break;
    }

    Global.waitingToValidUsername = null;
    Global.session = null;
    Rms.deleteSession();
  }

  public void onGameServiceList(DataPackage dataPackage) {
    int size = dataPackage.nextInt();
    for (int i = 0; i < size; i++) {
      String id = dataPackage.nextString();
      int concurrentUser = dataPackage.nextInt();

      for (int j = 0; j < Global.gameServices.size(); j++) {
        Service gameService = (Service) Global.gameServices.elementAt(j);
        if (gameService.getId().equals(id)) {
          gameService.setCocurrentUser(concurrentUser);
          break;
        }
      }
    }
  }

  public void onSaltResponse(DataPackage dataPackage) {
    String salt = dataPackage.nextString();
    SocketClientUtil.authenticateByPassword(Global.currentUser.getName(), Global.currentUser.getPasswordMd5(), salt);
  }

  public void onReceiveUserInfo(DataPackage dataPackage) {
    String username = dataPackage.nextString();
    if (username.equals(Global.currentUser.getName())) {
      Global.currentUser.setAvatarId(dataPackage.nextString());
      Global.currentUser.setMoney(dataPackage.nextInt());
      Global.currentUser.setGold(dataPackage.nextInt());
      Global.currentUser.setProviderId(dataPackage.nextInt());
      Global.currentUser.setLevel(dataPackage.nextInt());
      Global.currentUser.setExperience(dataPackage.nextInt());
      Global.currentUser.setGender(dataPackage.nextString());
      Global.currentUser.setMobile(dataPackage.nextString());
      Global.currentUser.setFullName(dataPackage.nextString());
      Global.currentUser.setBirthDay(dataPackage.nextString());
      Global.currentUser.setBirthMonth(dataPackage.nextString());
      Global.currentUser.setBirthYear(dataPackage.nextString());
      Global.currentUser.setEmail(dataPackage.nextString());
      Global.currentUser.setAddress(dataPackage.nextString());
      Global.currentUser.setStatus(dataPackage.nextString());
      Global.currentUser.setTongSoTran(dataPackage.nextInt());
      Global.currentUser.setSoTranThang(dataPackage.nextInt());
      Global.currentUser.setSoTranThua(dataPackage.nextInt());
      Global.currentUser.setNextLevelExp(dataPackage.nextInt());
      Global.currentUser.setGroupId(dataPackage.nextInt());
      String strGroupMaster = dataPackage.nextString();
      if (strGroupMaster.equalsIgnoreCase("true")) {
        Global.currentUser.setGroupMaster(true);
      } else {
        Global.currentUser.setGroupMaster(false);
      }
      ByteArray avatarGroup = dataPackage.nextByteArray();
      Global.currentUser.setAvatarGroup(state.GameImage.createImage(avatarGroup, 0, avatarGroup.len()));
      Global.userCachedMap.put(username, Global.currentUser);
      FrmUserInfo frmUserInfo = (FrmUserInfo) FrmUserInfo.instance();
      frmUserInfo.updateUserInfo(username);

      if (Global.tableUsers != null) {
        for (int i = 0; i < Global.tableUsers.size(); i++) {
          User user = (User) Global.tableUsers.elementAt(i);
          if (Global.currentUser.getName().equals(user.getName())) {
            user.setMoney(Global.currentUser.getMoney());
            user.setGold(Global.currentUser.getGold());
          }
        }
      }
    } else {
      User user = new User(username);
      user.setAvatarId(dataPackage.nextString());
      user.setMoney(dataPackage.nextInt());
      user.setGold(dataPackage.nextInt());
      user.setProviderId(dataPackage.nextInt());
      user.setLevel(dataPackage.nextInt());
      user.setExperience(dataPackage.nextInt());
      user.setGender(dataPackage.nextString());
      user.setMobile(dataPackage.nextString());
      user.setFullName(dataPackage.nextString());
      user.setBirthDay(dataPackage.nextString());
      user.setBirthMonth(dataPackage.nextString());
      user.setBirthYear(dataPackage.nextString());
      user.setEmail(dataPackage.nextString());
      user.setAddress(dataPackage.nextString());
      user.setStatus(dataPackage.nextString());
      user.setTongSoTran(dataPackage.nextInt());
      user.setSoTranThang(dataPackage.nextInt());
      user.setSoTranThua(dataPackage.nextInt());
      user.setNextLevelExp(dataPackage.nextInt());
      user.setGroupId(dataPackage.nextInt());
      String strGroupMaster = dataPackage.nextString();
      if (strGroupMaster.equalsIgnoreCase("true")) {
        user.setGroupMaster(true);
      } else {
        user.setGroupMaster(false);
      }
      ByteArray avatarGroup = dataPackage.nextByteArray();
      user.setAvatarGroup(state.GameImage.createImage(avatarGroup, 0, avatarGroup.len()));
      Global.userCachedMap.put(username, user);
      FrmUserInfo frmUserInfo = (FrmUserInfo) FrmUserInfo.instance();
      frmUserInfo.updateUserInfo(username);

      if (Global.tableUsers != null) {
        for (int i = 0; i < Global.tableUsers.size(); i++) {
          User usr = (User) Global.tableUsers.elementAt(i);
          if (user.getName().equals(usr.getName())) {
            usr.setMoney(user.getMoney());
            usr.setGold(user.getGold());
          }
        }
      }
    }
  }

  public void onChangeUserInfoSuccess(DataPackage dataPackage) {
    Global.alert.showAlert3(this, GameAlert.OK_TYPE, StringArray.create1( "Cập nhật thông tin tài khoản", "thành công" ));
  }

  public void onChangeUserInfoFail(DataPackage dataPackage) {
    Global.alert.showAlert3(this, GameAlert.OK_TYPE, StringArray.create1( "Cập nhật thông tin tài khoản", "thất bại" ));
  }

  public void onNoUpdateResponse(DataPackage dataPackage) {
    FrmDownloadResource frmDownloadResource = (FrmDownloadResource) FrmDownloadResource.instance();
    frmDownloadResource.message = "Đang kiểm tra dữ liệu...";
  }
  
  public void onReceiveNumberOfUserOnline(DataPackage dataPackage) {
    Global.numberOfUserOnline = dataPackage.nextInt();
  }

  public void onUpdateClienResponse(DataPackage dataPackage) {
    updateUrl = dataPackage.nextString();
    Global.isNeedToUpdate = true;
    GameGlobal.alert.showAlert1(this, GameAlert.YES_NO_TYPE, StringArray.create2( "Đã có phiên bản mới", "Bạn có muốn cập nhật", " phiên bản mới không?" ), 98);
  }

  public void onUpdateProviderResponse(DataPackage dataPackage) {
    Global.provider = new Provider(dataPackage.nextInt());
    Rms.saveProvider(Global.provider);
  }

  public void onRegisterSuccess(DataPackage dataPackage) {
    GameGlobal.alert.showAlert(this, GameAlert.OK_TYPE, "Đăng ký thành công");
  }

  public void onRegisterFail(DataPackage dataPackage) {
    // dataPackage.nextString(); // get username (not use)
    int errorCode = dataPackage.nextInt();
    switch (errorCode) {
    case ProtocolConstants.ErrorCode.USER_NAME_EXIST_ERROR:
      GameGlobal.alert.showAlert(this, GameAlert.OK_TYPE, "Tên tài khoản đã được sử dụng");
      break;
    case ProtocolConstants.ErrorCode.USER_NAME_TOO_LONG_ERROR:
      GameGlobal.alert.showAlert3(this, GameAlert.OK_TYPE, StringArray.create1( "Tên đăng nhập phải", "ngắn hơn " + Constants.USER_NAME_MAX_LEN + " ký tự" ));
      break;
    case ProtocolConstants.ErrorCode.USER_NAME_TOO_SHORT_ERROR:
      GameGlobal.alert.showAlert3(this, GameAlert.OK_TYPE, StringArray.create1( "Tên đăng nhập phải", "dài hơn " + Constants.USER_NAME_MIN_LEN + " ký tự" ));
      break;
    case ProtocolConstants.ErrorCode.USER_NAME_NOT_VALID:
      GameGlobal.alert.showAlert(this, GameAlert.OK_TYPE, "Tên tài khoản không hợp lệ");
      break;
    default:
      GameGlobal.alert.showAlert(this, GameAlert.OK_TYPE, "Tạo tài khoản thất bại");
      break;
    }
  }

  public void onChangePasswordSuccess(DataPackage dataPackage) {
    GameGlobal.alert.showAlert(this, GameAlert.OK_TYPE, "Đổi mật khẩu thành công");
  }

  public void onChangePasswordFail(DataPackage dataPackage) {
    dataPackage.nextString(); // get username (not use)
    int errorCode = dataPackage.nextInt();
    switch (errorCode) {
    case ProtocolConstants.ErrorCode.PASSWORD_NOT_CORRECT_ERROR:
      GameGlobal.alert.showAlert(this, GameAlert.OK_TYPE, "Mật khẩu cũ không đúng");
      break;
    case ProtocolConstants.ErrorCode.USER_NOT_EXIST_ERROR:
      GameGlobal.alert.showAlert(this, GameAlert.OK_TYPE, "Tài khoản không tồn tại");
      break;
    default:
      GameGlobal.alert.showAlert(this, GameAlert.OK_TYPE, "Đổi mật khẩu thất bại");
      break;
    }
  }

  public void onMoneyChange(DataPackage dataPackage) {
    Global.currentUser.setMoney(dataPackage.nextInt());
    Global.currentUser.setGold(dataPackage.nextInt());
    if (Global.tableUsers != null) {
      for (int i = 0; i < Global.tableUsers.size(); i++) {
        User user = (User) Global.tableUsers.elementAt(i);
        if (Global.currentUser.getName().equals(user.getName())) {
          user.setMoney(Global.currentUser.getMoney());
          user.setGold(Global.currentUser.getGold());
        }
      }
    }
  }

  public void onDownloadUrlReceive(DataPackage dataPackage) {
    Global.downloadUrl = dataPackage.nextString();
  }
  
  public void onHelpContentResponse(DataPackage dataPackage) {
    String helpContent = dataPackage.nextString();
    FrmGuide frmGuide = (FrmGuide) FrmGuide.instance();
    frmGuide.helpText = helpContent;
  }

  public void onExchangeRateResponse(DataPackage dataPackage) {
    float exchangeRate = dataPackage.nextDouble();
    FrmMoneyToGoldExchange frmMoneyToGoldExchange = (FrmMoneyToGoldExchange) FrmMoneyToGoldExchange.instance();
    frmMoneyToGoldExchange.onExchangeRateResponse(exchangeRate);
  }

  public void onChangMoneyToGoldSuccess(DataPackage dataPackage) {
    FrmMoneyToGoldExchange frmMoneyToGoldExchange = (FrmMoneyToGoldExchange) FrmMoneyToGoldExchange.instance();
    frmMoneyToGoldExchange.onChangeMoneyToGoldSuccess();
  }

  public void onChangMoneyToGoldFail(DataPackage dataPackage) {
    FrmMoneyToGoldExchange frmMoneyToGoldExchange = (FrmMoneyToGoldExchange) FrmMoneyToGoldExchange.instance();
    frmMoneyToGoldExchange.onChangeMoneyToGoldFail();
  }

  public void onUpdateGameVersionInfo(DataPackage dataPackage) {
    Constants.GAME_VERSION_INFO = dataPackage.nextString();
  }

  public void onImageResponse(DataPackage dataPackage) {
    String category = dataPackage.nextString();
    String fileName = dataPackage.nextString();
    ByteArray data = dataPackage.nextByteArray();

    // Get resource category
    Hashtable resourceByCategory = (Hashtable) Global.resourceCategory.get(category);
    if (resourceByCategory == null) {
      resourceByCategory = new Hashtable();
      Global.resourceCategory.put(category, resourceByCategory);
    }

    // Store resource
    if (resourceByCategory.get(fileName) == null) {
      resourceByCategory.put(fileName, new Integer(ResourceRms.saveImageData(category, data)));
      ResourceRms.saveMasterRecord(category, resourceByCategory);
      ResourceManager.updateImage(category, fileName, GameImage.createImage(data, 0, data.len()).getImage());
    }
  }

  public void onReceiveNotificationMessage(DataPackage dataPackage) {
    String notificationMessage = dataPackage.nextString();
    int showTime = dataPackage.nextInt();
    int fontSize = dataPackage.nextInt();
    int backgroundColor = dataPackage.nextInt();
    int foregroundColor = dataPackage.nextInt();
    FrmDisplayNotificationMessage frmDisplayNotificationMessage = (FrmDisplayNotificationMessage) FrmDisplayNotificationMessage.instance();
    frmDisplayNotificationMessage.displayNotify(notificationMessage, showTime, fontSize, backgroundColor, foregroundColor);
  }

  public void onReceiveConfigToDisableGameAndApp(DataPackage dataPackage) {
    // Read the config from server
    String configToDisableGame = dataPackage.nextString();
    String configToDisableApp = dataPackage.nextString();
    Global.gameToReject = configToDisableGame.equalsIgnoreCase("null") ? Global.gameToReject : GameStringUtils.split(configToDisableGame, ",");
    Global.appToReject = configToDisableApp.equalsIgnoreCase("null") ? Global.appToReject : GameStringUtils.split(configToDisableApp, ",");

    // Init game and app list again
    Global.initGameList();
    FrmChooseApp frmChooseApp = (FrmChooseApp) FrmChooseApp.instance();
    frmChooseApp.initAppList();
  }
  
  public void onReceiveAutoPlusGoldMessage(DataPackage dataPackage){
    String msg = dataPackage.nextString();
    StringArray arrMsg = GameStringUtils.split(msg, "@@@");
    Global.alert.showAlert3(this, GameAlert.OK_TYPE, arrMsg);
  }
}
